home *** CD-ROM | disk | FTP | other *** search
- /*
- * HSCHMOO.CPP
- * Handler for Schmoo, Chapter 11.
- *
- * DLL exports for an object handler as well as class factory.
- *
- * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
- *
- * Kraig Brockschmidt, Software Design Engineer
- * Microsoft Systems Developer Relations
- *
- * Internet : kraigb@microsoft.com
- * Compuserve: >INTERNET:kraigb@microsoft.com
- */
-
-
- #define INITGUIDS
- #include "hschmoo.h"
-
-
- //Count number of objects and number of locks.
- ULONG g_cObj=0;
- ULONG g_cLock=0;
-
- //DLL Instance handle
- HINSTANCE hgInst;
-
-
- /*
- * LibMain
- *
- * Purpose:
- * DLL-specific entry point called from LibEntry.
- *
- * Parameters:
- * hInst HINSTANCE instance of the DLL.
- * wDataSeg WORD segment selector of the DLL's data segment.
- * wHeapSize WORD byte count of the heap.
- * lpCmdLine LPSTR to command line used to start the module.
- *
- * Return Value:
- * HANDLE Instance handle of the DLL.
- *
- */
-
- HANDLE FAR PASCAL LibMain(HINSTANCE hInst, WORD wDataSeg
- , WORD cbHeapSize, LPSTR lpCmdLine)
- {
- if (0!=cbHeapSize)
- UnlockData(0);
-
- hgInst=hInst;
- return hInst;
- }
-
-
-
-
-
- /*
- * WEP
- *
- * Purpose:
- * Required DLL Exit function. Does nothing.
- *
- * Parameters:
- * bSystemExit BOOL indicating if the system is being shut
- * down or the DLL has just been unloaded.
- *
- * Return Value:
- * void
- *
- */
-
- void FAR PASCAL WEP(int bSystemExit)
- {
- return;
- }
-
-
-
-
-
-
- /*
- * DllGetClassObject
- *
- * Purpose:
- * Provides an IClassFactory for a given CLSID that this DLL is
- * registered to support. This DLL is placed under the CLSID
- * in the registration database as the InProcServer.
- *
- * Parameters:
- * clsID REFCLSID that identifies the class factory desired.
- * Since this parameter is passed this DLL can handle
- * any number of objects simply by returning different
- * class factories here for different CLSIDs.
- *
- * riid REFIID specifying the interface the caller wants
- * on the class object, usually IID_ClassFactory.
- *
- * ppv LPVOID FAR * in which to return the interface pointer.
- *
- * Return Value:
- * HRESULT NOERROR on success, otherwise contains an error SCODE.
- */
-
- HRESULT __export FAR PASCAL DllGetClassObject(REFCLSID rclsid, REFIID riid
- , LPVOID FAR *ppv)
- {
- if (!IsEqualCLSID(rclsid, CLSID_Schmoo2Figure))
- return ResultFromScode(E_FAIL);
-
- //Check that we can provide the interface
- if (!IsEqualIID(riid, IID_IUnknown) && !IsEqualIID(riid, IID_IClassFactory))
- return ResultFromScode(E_NOINTERFACE);
-
- //Return our IClassFactory for Figure objects
- *ppv=(LPVOID)new CFigureClassFactory;
-
- if (NULL==*ppv)
- return ResultFromScode(E_OUTOFMEMORY);
-
- //Don't forget to AddRef the object through any interface we return
- ((LPUNKNOWN)*ppv)->AddRef();
-
- return NOERROR;
- }
-
-
-
-
-
- /*
- * DllCanUnloadNow
- *
- * Purpose:
- * Answers if the DLL can be freed, that is, if there are no
- * references to anything this DLL provides.
- *
- * Parameters:
- * None
- *
- * Return Value:
- * BOOL TRUE if nothing is using us, FALSE otherwise.
- */
-
- STDAPI DllCanUnloadNow(void)
- {
- SCODE sc;
-
- //Our answer is whether there are any object or locks
- sc=(0L==g_cObj && 0==g_cLock) ? S_OK : S_FALSE;
- return ResultFromScode(sc);
- }
-
-
-
-
- /*
- * ObjectDestroyed
- *
- * Purpose:
- * Function for the Figure object to call when it gets destroyed.
- * Since we're in a DLL we only track the number of objects here
- * letting DllCanUnloadNow take care of the rest.
- *
- * Parameters:
- * None
- *
- * Return Value:
- * None
- */
-
- void FAR PASCAL ObjectDestroyed(void)
- {
- g_cObj--;
- return;
- }
-
-
-
-
-
-
- /*
- * CFigureClassFactory::CFigureClassFactory
- *
- * Purpose:
- * Constructor for an object supporting an IClassFactory that
- * instantiates Figure objects.
- *
- * Parameters:
- * None
- */
-
- CFigureClassFactory::CFigureClassFactory(void)
- {
- m_cRef =0L;
- return;
- }
-
-
-
-
-
- /*
- * CFigureClassFactory::~CFigureClassFactory
- *
- * Purpose:
- * Destructor for a CFigureClassFactory object. This will be
- * called when we ::Release the object to a zero reference count.
- */
-
- CFigureClassFactory::~CFigureClassFactory(void)
- {
- return;
- }
-
-
-
-
-
-
- /*
- * CFigureClassFactory::QueryInterface
- * CFigureClassFactory::AddRef
- * CFigureClassFactory::Release
- *
- * Purpose:
- * IUnknown implementations for this object.
- */
-
- STDMETHODIMP CFigureClassFactory::QueryInterface(REFIID riid, LPVOID FAR *ppv)
- {
- *ppv=NULL;
-
- //Any interface on this object is the object pointer.
- if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
- *ppv=(LPVOID)this;
-
- /*
- * If we actually assign an interface to ppv we need to AddRef it
- * since we're returning a new pointer.
- */
- if (NULL!=*ppv)
- {
- ((LPUNKNOWN)*ppv)->AddRef();
- return NOERROR;
- }
-
- return ResultFromScode(E_NOINTERFACE);
- }
-
-
- STDMETHODIMP_(ULONG) CFigureClassFactory::AddRef(void)
- {
- return ++m_cRef;
- }
-
-
- STDMETHODIMP_(ULONG) CFigureClassFactory::Release(void)
- {
- ULONG cRefT;
-
- cRefT=--m_cRef;
-
- if (0L==m_cRef)
- delete this;
-
- return cRefT;
- }
-
-
-
-
-
-
-
- /*
- * CFigureClassFactory::CreateInstance
- *
- * Purpose:
- * Instantiates a Figure object that supports the IFigure
- * and IUnknown interfaces. If the caller asks for a different
- * interface than these two then we fail.
- *
- * Parameters:
- * punkOuter LPUNKNOWN to the controlling IUnknown if we are
- * being used in an aggregation.
- * riid REFIID identifying the interface the caller desires
- * to have for the new object.
- * ppvObj LPVOID FAR * in which to store the desired interface
- * pointer for the new object.
- *
- * Return Value:
- * HRESULT NOERROR if successful, otherwise contains E_NOINTERFACE
- * if we cannot support the requested interface.
- */
-
- STDMETHODIMP CFigureClassFactory::CreateInstance(LPUNKNOWN punkOuter
- , REFIID riid, LPVOID FAR *ppvObj)
- {
- LPCFigure pObj;
- HRESULT hr;
-
- *ppvObj=NULL;
- hr=ResultFromScode(E_OUTOFMEMORY);
-
- //Verify that if there is a controlling unknown it's asking for IUnknown
- if (NULL!=punkOuter && !IsEqualIID(riid, IID_IUnknown))
- return ResultFromScode(E_NOINTERFACE);
-
- //Create the object. This also creates a window.
- pObj=new CFigure(punkOuter, ObjectDestroyed, hgInst);
-
- if (NULL==pObj)
- return hr;
-
- if (pObj->FInit())
- hr=pObj->QueryInterface(riid, ppvObj);
-
- //Kill the object if initial creation or FInit failed.
- if (FAILED(hr))
- delete pObj;
- else
- g_cObj++;
-
- return hr;
- }
-
-
-
-
-
-
- /*
- * CFigureClassFactory::LockServer
- *
- * Purpose:
- * Increments or decrements the lock count of the DLL. If the lock
- * count goes to zero and there are no objects, the DLL is allowed
- * to unload. See DllCanUnloadNow.
- *
- * Parameters:
- * fLock BOOL specifying whether to increment or decrement the
- * lock count.
- *
- * Return Value:
- * HRESULT NOERROR always.
- */
-
- STDMETHODIMP CFigureClassFactory::LockServer(BOOL fLock)
- {
- if (fLock)
- g_cLock++;
- else
- g_cLock--;
-
- return NOERROR;
- }
-